# pylint: disable-msg=E1101
"""Helper functions

Consists of functions to typically be used within templates, but also
available to Controllers. This module is available to templates as 'h'.
"""
# Import helpers as desired, or define your own, ie:
#from webhelpers.html.tags import checkbox, password

import json
from datetime import datetime

from pylons import request, url, config
from pylons.i18n import lazy_ugettext as _
from sqlalchemy import and_, desc
from babel import dates
from repoze.what.predicates import not_anonymous as _not_anonymous

from webhelpers.html import tags, url_escape
from webhelpers.html.tags import link_to
from webhelpers.html.builder import HTML
from webhelpers.containers import distribute

from chowa.model.site import *
from chowa.model.layout import *
from chowa.lib.base import render, Session
from chowa.lib.site.navigation import url_generator as url_gen, url_outside, get_global_tabs

__all__ = ['link_to',
           'panel', 'tabs', 'message_box',
           'month_name', 'format_date', 'format_datetime',
           'dropdown', 'select_month', 'select_bool',
           'js', 'css', 'img', 'scripts',
           'options_list', 'checkboxes', 'links_grid', 'years_chooser',
           'url_gen', 'url_escape', 'url_outside',
           'user_online',
           'save_button', 'back_button', 'next_button',
           'theme', 'distribute', 'comments',
           'not_anonymous', 'print_version']

def panel(panel_name):
    """Render panel by name."""
    # get application name
    app_name = config['pylons.package']
    
    # get panel blocks
    q = Session.query(PanelBlock).join(Panel).join(panel_block_apps).join(App)
    blocks = q.filter(and_(
        Panel.name==panel_name,
        App.name.in_([app_name, '*'])
    ))
    
    # generate blocks for context
    blocks_context = []
    blocks = sorted(blocks, key=lambda block: block.weight)
    for block in blocks:
        if block.login_required and not request.remote_user:
            continue
        tokens = block.component.split('.')
        module_name = tokens[-2].__str__()
        components = __import__('.'.join(tokens[0:-2]), fromlist=[module_name])
        module = components.__dict__[tokens[-2]]
        
        options = {}
        try:
            options = json.loads(block.options)
        except Exception:
            pass
        
        # load the component's class
        component = getattr(module, tokens[-1])(options)
        blocks_context += [component]
    return render('/layout/panel_blocks.html',
                  extra_vars={'blocks': blocks_context})


def tabs(level):
    """
    Render tabs depending on routing variables
    """
    controller = request.environ['pylons.controller']
    
    _tabs = get_global_tabs(level)
    # add tabs from controller
    tabs_attr = '__%s_tabs__' % level
    if hasattr(controller, tabs_attr):
        _tabs += getattr(controller, tabs_attr)
    
    # add tabs from __init__ modules
    segments = controller.__module__.split('.')
    for depth in range(2, len(segments)):
        pkg = '.'.join(segments[:depth])
        try:
            pkg_module = __import__(pkg, fromlist=[tabs_attr])
            _tabs += getattr(pkg_module, tabs_attr)
        except:
            pass
        
    for tab_group in _tabs:
        if _verify_tab_group(tab_group):
            tabs_context = []
            for tab in tab_group:
                tab_context = {
                    'url': tab.get_url(),
                    'caption': tab.caption,
                    'description': tab.description,
                    'is_current': tab.verify(),
                }
                tabs_context += [tab_context]
            return render('/layout/tabs.html', extra_vars={'tabs': tabs_context}) 
    return ''

def _verify_tab_group(tab_group):
    for tab in tab_group:
        if tab.verify(): return True
    return False


def message_box():
    identity = request.environ.get('repoze.who.identity')
    if identity:
        user = identity['user']
        query = Session.query(Receipt)
        query = query.join(Message)
        query = query.filter(Receipt.recipient_id == user.id)
        query = query.filter(Receipt.is_read == False)
        messages = query.order_by(desc(Message.created)).all()
        return render('/social/messaging/message_box.html', extra_vars={'messages': messages})
    return ''


def month_name(month, width='abbreviated', context='stand-alone'):
    return dates.get_month_names(width, context=context).get(month)


def dropdown(name, selected, options, **kwargs):
    return tags.select(name, [selected], options, **kwargs)


def select_month(name, selected, width='wide', context='stand-alone', **kwargs):
    months = dates.get_month_names(width=width, context=context)
    return tags.select(name, [selected], [(i, months[i]) for i in months], **kwargs)

def select_bool(name, selected):
    return tags.select(name, [selected], [(1, _('Yes')),
                                          (0, _('No'))])

def format_date(date_, format='long'):
    return dates.format_date(date_, format).replace(u'\u02bc', "'")

def format_datetime(datetime_, format='long'):
    return dates.format_datetime(datetime_, format).replace(u'\u02bc', "'")


def js(path):
    return '%s/js/%s' % (config.get('url_prefix'), path)

def css(path):
    return '%s/css/%s' % (config.get('url_prefix'), path)

def img(path):
    return '%s/img/%s' % (config.get('url_prefix'), path)

def scripts():
    files = [
        'jquery-1.4.2.min.js',
        'jquery.form.js',
        'jquery.timers.js',
        'jquery.ui.core.js',
        'jquery.ui.datepicker.js',
        'jquery.ui.datepicker-%s.js' % config.get('lang'),
        'chowa.js']
    html = ''
    for file in files:
        html += HTML.tag('script', type='text/javascript', src='/js/' + file)
    return html


def options_list(options, param_name, chosen=None, class_='choice', ignore_params=[]):
    def _url_gen(value):
        kw = dict().fromkeys(ignore_params)
        kw[param_name] = value
        return url_gen(**kw)
    if chosen:
        item = HTML.tag('a', href=_url_gen(None),
                        c=HTML.literal(_('All')))
    else:
        item = HTML.tag('span', c=HTML.literal(_('All')))
    items = [item]
    for option in options:
        if chosen and option.id == int(chosen):
            item = HTML.tag('span', c=HTML.literal(option))
        else:
            item = HTML.tag('a', href=_url_gen(option.id),
                            c=HTML.literal(option))
        items += [item]
    html = tags.ul(items, class_=class_)
    return html


def checkboxes(items, prefix, checked_items=[], cols=1):
    table = distribute(items, cols, 'V')
    trs = HTML.literal()
    for row in table:
        tds = HTML.literal()
        for item in row:
            if item:
                is_checked=None
                if item.id in [checked.id for checked in checked_items]:
                    is_checked = 'checked'
                checkbox = HTML.tag('input', type='checkbox', name=prefix+str(item.id), checked=is_checked)
                label = HTML.tag('label', HTML.literal(item))
                tds += HTML.tag('td', checkbox + label)
        trs += HTML.tag('tr', tds)
    return trs


def links_grid(items, cols, **kwargs):
    table = distribute(items, cols, 'V')
    trs = HTML.literal()
    nrow = 0
    for row in table:
        tds = HTML.literal()
        ncol = 0
        for item in row:
            if item:
                link = link_to(HTML.literal(item), url=url(id=item.id, **kwargs))
                class_ = 'field' + str(nrow % 2) + str(ncol % 2)
                tds += HTML.tag('td', link, class_=class_)
                ncol += 1
        trs += HTML.tag('tr', tds)
        nrow += 1
    return trs


def years_chooser(years, current):
    items = HTML.literal()
    for year in years:
        if str(year) == str(current):
            items += HTML.tag('span',
                              class_='pager_curpage',
                              c=HTML.literal(year))
        else:
            items += HTML.tag('a', href=url_gen(year=year),
                              class_='pager_link',
                              c=HTML.literal(year))
    html = HTML.tag('div', class_='paginator years', c=items)
    return html


def user_online(user):
    html = HTML.literal()
    if user.is_online:
        caption = '@' + HTML.literal(_('online'))
        user_id = HTML.tag('span', class_='user-id', c=HTML.literal(user.id))
        html = HTML.tag('a', class_='online', c=caption+user_id)
    return html


def save_button(disabled=True):
    if disabled:
        button = tags.submit('save-button', _('Save'),
                             id='save-button',
                             class_="disabled-button big",
                             disabled=True)
    else:
        button = tags.submit('save-button', _('Save'),
                             id='save-button',
                             class_="submit-button big") 
    html = HTML.tag('div', align='center', c=button)
    return html

def back_button():
    return tags.submit('back', HTML.literal('&lt;&lt; ' + unicode(_('Back'))),
                        class_='submit-button big')

def next_button():
    return tags.submit('next', HTML.literal(unicode(_('Next')) + ' &gt;&gt;'),
                        class_='submit-button big')


def theme():
    page_layout = request.params.get('page_layout')
    if page_layout:
        return page_layout
    identity = request.environ.get('repoze.who.identity')
    if identity:
        user = identity['user']
        if user.theme:
            return user.theme.name
    return u'default'


def comments(topic_id):
    html = HTML.tag('div', id='comments-load')
    html += link_to('', class_='hidden-url',
                    url=url_outside('chowa',
                                    controller='social/comments',
                                    action='view',
                                    id=topic_id))
    return html


# Access controll

def not_anonymous():
    return _not_anonymous().is_met(request.environ)

def print_version():
    return link_to(_('Print version'), url_gen(page_layout='print'), target='_blank')
